package ikastola

import java.util.List;
import java.util.Map;

import beans.PaymentStudentRecord
import beans.StudentBalanceRecord
import org.ikastola.BalanceFees;
import org.ikastola.Course;
import org.ikastola.Fee
import org.ikastola.Student;
import org.joda.time.DateTime
import org.springframework.transaction.annotation.Transactional

import utils.Utils;

@Transactional(readOnly = true)
class BalanceFeesService {

	/**
	 * 
	 * 	Dado un curso y un MES limite del año:
	 *     Obtener todos los alumnos del curso:
	 * 		  Por cada alumno del curso recuperar todos los pago hasta el MES limite ordenado ascendente por paymentdate
	 *          Matricula - Enero - Febrero - Marzo - .... - MES limite
	 * 
	 * @param course
	 * @param month
	 * @param year
	 * @param fee
	 * @return
	 */
    def getBalancesByCourseAndDate(Course course, int month, int year, Fee fee) {
		
		List<StudentBalanceRecord> result = []
		
		DateTime iniDate = new DateTime().withYear(year).monthOfYear().withMinimumValue().dayOfMonth().withMinimumValue()
		DateTime endDate = new DateTime().withYear(year).withMonthOfYear(month).dayOfMonth().withMaximumValue()
		
		def students = Student.findAllByCourseAndDeleted(course,Constants.NOT_DELETED)
		def balances
				
		for (Student s in students) {
			
			balances = BalanceFees.executeQuery("from BalanceFees b where b.deleted = ? and b.student = ? and b.fee = ? and b.paymentdate >= ? and b.paymentdate <= ? order by b.paymentdate asc",  [Constants.NOT_DELETED, s, fee, iniDate.toDate(), endDate.toDate()])

			Map<Integer, List<BalanceFees>> mapBalanceFees = [:]
			StudentBalanceRecord record = new StudentBalanceRecord()
			record.setFullName(String.valueOf(s.getName().charAt(0))+'. '+s.getLastname())
			record.setDocnumber(s.getDocnumber())
			
			for (b in balances) {
				
				DateTime d = new DateTime(b.getPaymentdate())
				Integer key
				if (Constants.FEE_PERIOD_MONTH.equals(b.getFee().getPeriod())) { 
					key =  d.getMonthOfYear()
				}
				else {
					key =  d.getYear()
				}
				
				if (!mapBalanceFees.containsKey(key)) {
						List<BalanceFees> balanceFees = []
						balanceFees.add(b)
						mapBalanceFees.put(key, balanceFees)
				} else {
						List<BalanceFees> balanceFees = mapBalanceFees.get(key)
						balanceFees.add(b)
						mapBalanceFees.put(key, balanceFees)
				}
			}
			
			record.setMapBalanceFees(mapBalanceFees)
			result.add(record)
		}
		return result
	}
	
	def getAnnualPaymentStudentBeans(List<StudentBalanceRecord> balances) {
		List<PaymentStudentRecord> records = []
		
		for (StudentBalanceRecord b in balances) {
			
			PaymentStudentRecord r = new PaymentStudentRecord()
			
			r.setFullName(b.getFullName())
			
			Double totalPay = 0.0
			
			Map<Integer, List<BalanceFees>> m = b.getMapBalanceFees()
				
			for(Integer key in m.keySet()) {
				List<BalanceFees> bFees = m.get(key)
				Map<Fee,Double> totalByFee = getTotalByFee(bFees)
				String data = ""
				for (Fee k in totalByFee.keySet()) {
					Double total = totalByFee.get(k)
					data = data + String.valueOf(total)
					totalPay = Utils.round(totalPay + total)
				}
				r.setMonth2(data)
			}
			r.setTotalPay(totalPay)
			records.add(r)
		}
		return records
	}
	
	def getMonthlyPaymentStudentBeans(List<StudentBalanceRecord> balances) {
		
		List<PaymentStudentRecord> records = []
		
		for (StudentBalanceRecord b in balances) {
			
			PaymentStudentRecord r = new PaymentStudentRecord()
			
			r.setFullName(b.getFullName())
			
			Double totalPay = 0.0
			
			Map<Integer, List<BalanceFees>> m = b.getMapBalanceFees()
				
			for(Integer month = 2; month <= 12; month++) {
			
				if (m.containsKey(month)) {
					List<BalanceFees> bFees = m.get(month)
					Map<Fee,Double> totalByFee = getTotalByFee(bFees)
					String data = ""
					for (Fee k in totalByFee.keySet()) {
						Double total = totalByFee.get(k)
						data = data + String.valueOf(total)
						totalPay = Utils.round(totalPay + total)
					}
					switch(month) {
						case 2:
							r.setMonth2(data)
							break
						case 3:
							r.setMonth3(data)
							break
						case 4:
							r.setMonth4(data)
							break
						case 5:
							r.setMonth5(data)
							break
						case 6:
							r.setMonth6(data)
							break
						case 7:
							r.setMonth7(data)
							break
						case 8:
							r.setMonth8(data)
							break
						case 9:
							r.setMonth9(data)
							break
						case 10:
							r.setMonth10(data)
							break
						case 11:
							r.setMonth11(data)
							break
						case 12:
							r.setMonth12(data)
							break
						default:
							r.setMonth1("")	
					}
				}
			}
			r.setTotalPay(totalPay)
			records.add(r)
		}
		return records		
	}
				
		
	def getTotalByFee(List<BalanceFees> balances) {
		def totalByFee = [:]
		for (BalanceFees b in balances) {
			Fee f = b.getFee()
			if (!totalByFee.containsKey(f)) {
				totalByFee.put(f, b.getAmount())
			}
			else {
				Double total = totalByFee.get(f)
				total = Utils.round(total + b.getAmount())
				totalByFee.put(f, total)
			}
		}
		return totalByFee
	}
}
